﻿#region Usings

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Web.Mvc;
using Omu.Awesome.Core;
using XPressify.Data.CompliedQueries;
using XPressify.Data.Helpers;
using XPressify.Helpers;
using XPressify.Models;
using XPressify.Data;
using XPressify.Core;

#endregion

namespace XPressify.Controllers
{
    public class EventController : SubjectController
    {
        //
        // GET: /Event/
        [Authorize]
        public ActionResult EventOwnerList(int? page)
        {
            var repo = Repository;
            var currentUser = CurrentUser;
            var events = EventCompiledQueries.GetEventsOfDesc(repo as Repository, currentUser.Id);
            var eventPageable = events.GetPageable(page ?? 1, 5, (g => g.Created));
            var models = new List<ListEventModel>();
            foreach (var @event in eventPageable.Page)
            {
                var organizer = Repository.GetAdminOf(@event.Id);

                var isMemberOfEvent = EventCompiledQueries.IsMemberOf(repo as Repository, currentUser.Id, @event.Id);

                var eventModel = new ListEventModel
                                     {
                                         Id = currentUser.Id,
                                         EventModel = @event,
                                         Organizer = organizer,
                                         IsOrganizer = currentUser.Id == organizer.Id,
                                         IsMemberOf = isMemberOfEvent
                                     };


                models.Add(eventModel); // add to models list
            }
            var eventModelPageable = new Pageable<ListEventModel> { Page = models, PageCount = eventPageable.PageCount, PageIndex = eventPageable.PageIndex };
            return View("EventList", eventModelPageable);
        }


        [Authorize]
        public ActionResult EventViewerList(Guid id, int? page) // when we try to open some events from other's  // id is from user we like to see
        {
            var repo = Repository;
            var viewerUser = CurrentUser;
            var ownerUser = UserCompiledQueries.GetUser(repo as Repository, id);

            var events = EventCompiledQueries.GetPublicEventsOfDesc(repo as Repository, ownerUser.Id);
             //select all events that are in relationship with selected id user && with privacy public

//            var eventPageable = events.GetPageable(page ?? 1, 2, (g => g.Created));

            var models = new List<ListEventModel>();
            foreach (var @event in events)
            {
                 // select organizer of the event
                var organizer = Repository.GetAdminOf(@event.Id);

                // try to find if current user is member of event
                var isMemberOfEvent = EventCompiledQueries.IsMemberOf(repo as Repository, viewerUser.Id, @event.Id);

                var eventModel = new ListEventModel
                {
                    EventModel = @event,
                    Organizer = organizer,
                    IsOrganizer = viewerUser.Id == organizer.Id,
                    IsMemberOf = isMemberOfEvent,
                    Id = id
                };


                models.Add(eventModel); // add to models list
            }
//            var eventModelPageable = new Pageable<ListEventModel> { Page = models, PageCount = eventPageable.PageCount, PageIndex = eventPageable.PageIndex };
            return View("EventViewerList", models);
        }



        //
        // GET: /Event/Details/5
        [Authorize]
        public ActionResult EventDetails(Guid id, Guid? postId)
        {
            var repo = Repository;
            var e = EventCompiledQueries.GetEvent(repo as Repository, id); 
            if(e == null)
            {
                // notify
                var notifyModel = new NotifyModel
                {
                    Title = "XPressify - Event",
                    Header = "Event",
                    Body = "Event does not exist",
                    NotificationType = NotificationType.Notification
                };
                return RedirectToAction("Notify", "Home", notifyModel);
            }
            var organizer = Repository.GetAdminOf(id);
            var user = CurrentUser;
            // try to find if organizer is one of the blocked user, if so then we not show it
            var organizerBlocked = EventCompiledQueries.IsAdminBlocked(repo as Repository, user.Id, organizer.Id); 
            var isMemberOfEvent = EventCompiledQueries.IsMemberOf(repo as Repository, user.Id, e.Id);

            var wallAlbum = AlbumCompiledQueries.GetWallAlbum(repo as Repository, e.Id);
            
            //get wall album cover picture
            var coverPicture = MediaCompiledQueries.GetCoverOf(repo as Repository, wallAlbum.Id);
            var wallAlbumSubject = AlbumCompiledQueries.GetAlbumSubject(repo as Repository, wallAlbum.Id);
            var path = "";
            var hasCoverPicture = true;
            if (coverPicture != null)
                path = "/Media/" + wallAlbumSubject.Id + "/" + wallAlbum.Id + "/" + coverPicture.Id + "." + coverPicture.FileType;
            else if (coverPicture == null && wallAlbum.IsProfile == false) 
            {
                path = "/Media/Image/DefaultCover.jpg";
                hasCoverPicture = false;
            }

            //get all posts from owner user and put them in dictionary
            var dictionary = new Dictionary<Post, List<Post>>();

            var allPosts = new List<Post>();

            if(postId != null)
            {
                var post = PostCompiledQueries.GetPost(repo as Repository, postId ?? Guid.Empty);
                allPosts.Add(post);
            }
            if(postId == null)
            {
                allPosts = PostCompiledQueries.GetAllPostsByPostSubjectIdOfDesc(repo as Repository, e.Id).ToList();
            }
            
            foreach (var post in allPosts)
            {
                var allComments = Repository.GetAllComments(post);
                dictionary.Add(post, allComments);
            }

            var currentUserProfilePicturePath = Repository.GetProfilePicturePath(user.Id);

            var model = new DetailsEventModel
                            {
                                Id = e.Id,
                                StartDate = e.StartDate,
                                EndDate = e.EndDate,
                                Location = e.Location,
                                Organizer = organizer,
                                Description = e.Description,
                                IsOrganizitor = organizer.Id == CurrentUser.Id,
                                OrganizerBlocked = organizerBlocked,
                                Name = e.Name,
                                IsMemberOf = isMemberOfEvent,
                                WallAlbumId = wallAlbum.Id,
                                AllPosts = dictionary,
                                CurrentUser = user,
                                CurrentUserProfilePicturePath = currentUserProfilePicturePath,
                                WallAlbumCoverPath = path,
                                EventPrivacyType = e.PrivacyType,
                                HasCoverPicture = hasCoverPicture,
                                MembersCanPost = e.MembersCanPost
                            };
            return View(model);
        }

        //
        // GET: /Event/Create
        [Authorize]
        public ActionResult EventCreate()
        {
            var model = new CreateEventModel();
            return View(model);
        }


        //
        // POST: /Event/Create
        [Authorize]
        [HttpPost]
        public ActionResult EventCreate(CreateEventModel model)
        {
            if(ModelState.IsValid)
            {
                try
                {
                    var e = new Event // create new event with CreateEventModel
                    {
                        Id = Guid.NewGuid(),
                        Created = DateTime.Now,
                        StartDate = model.StartDate,
                        EndDate = model.EndDate,
                        Location = model.Location,
                        Description = model.Description,
                        PrivacyType = Convert.ToInt16(model.Privacy),
                        Type = SubjectType.Event,
                        Name = model.Name,
                        MembersCanPost = model.MembersCanPost
                    };
                    Repository.AddObject(e);

                    // create organizer relationship
                    var relationship = new Relationship
                    // Create relationship with newly created event and organizer of event
                    {
                        Id = Guid.NewGuid(),
                        Type = ObjectType.Relationship,
                        Created = DateTime.Now,
                        Description = RelationshipType.AdministratorOfText,
                        BaseSubject = CurrentUser,
                        BaseSubject2 = e,
                        Status = RelationshipStatus.Confirmed,
                        RelationType = RelationshipType.AdministratorOf,
                        Name = RelationshipType.AdministratorOfText,
                        PrivacyType = ObjectPrivacy.FriendsOnly
                    };
                    Repository.AddObject(relationship);

                    var eventWallAlbum = new Album()
                                             {
                                                 BaseSubject = e,
                                                 Created = DateTime.Now,
                                                 Id = Guid.NewGuid(),
                                                 IsProfile = false,
                                                 IsWall = true,
                                                 Name = "Wall album",
                                                 Description = "",
                                                 MediaType = AlbumMediaType.Mix,
                                                 Type = ObjectType.Album,
                                                 PrivacyType = ObjectPrivacy.Everyone,
                                                 Location = ""
                                             };
                    Repository.AddObject(eventWallAlbum);

                    var newPostDummy = new Post
                                           {
                                               BaseObject = eventWallAlbum,
                                               BaseSubject = eventWallAlbum.BaseSubject,
                                               Content = "",
                                               Id = Guid.NewGuid(),
                                               Description = "Post dummy - wall album for event",
                                               Title = "Post dummy - wall album for event",
                                               Type = BaseMessageType.Post,
                                               PostType = PostType.PostDummy,
                                               Created = DateTime.Now,
                                               CommentType = CommentType.PostWithItsComments
                                           };
                    Repository.AddObject(newPostDummy);
                    Repository.SaveChanges();

                    //create physical folder
                    var path = Server.MapPath("~/Media/" + e.Id + "/"); // create a event directory
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path); // create directory
                    }
                    path = Server.MapPath("~/Media/" + e.Id + "/" +  eventWallAlbum.Id + "/");
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path); // create directory
                    }

                    return Json(model);
//                    return RedirectToAction("EventDetails", "Event", new {id = e.Id});
                }
                catch
                {
                    return View(model);
                }
            }
            return View(model);
        }


        [Authorize]
        public ActionResult EventEdit(Guid id)
        {
            var repo = Repository;
            var e = EventCompiledQueries.GetEvent(repo as Repository, id); 
            var user = CurrentUser;
            var admin = Repository.GetAdminOf(e.Id);
            if (admin == null || admin.Id != user.Id) // we check if current user is creator of event
            {
                return RedirectToAction("ProfileView", "Profile", new { id = user.Id });
            }
            var model = new EditEventModel
                            {
                                StartDate = e.StartDate,
                                EndDate = e.EndDate,
                                Location = e.Location,
                                Description = e.Description,
                                EventId = e.Id,
                                Name = e.Name,
                                MembersCanPost = e.MembersCanPost,
                                Privacy = e.PrivacyType.ToString()
                            };
            return View(model);
        }

        
        [Authorize]
        [HttpPost]
        public ActionResult EventEdit(Guid id, EditEventModel model)
        {
            if(ModelState.IsValid)
            {
                try
                {
                    var repo = Repository;
                    var e = EventCompiledQueries.GetEvent(repo as Repository, id); 

                    //put all new values in dictionary key = what value = new value // only if they are different so value is changed
                    var changes = new Dictionary<string, string>();
                    if (e.Name != model.Name)
                        changes.Add("name", model.Name);
                    if (e.Description != model.Description)
                        changes.Add("description", model.Description);
                    var privacy = Convert.ToInt16(model.Privacy);
                    if (e.PrivacyType != privacy)
                    {
                        var newValueString = privacy == SubjectPrivacy.Public ? "public" : "private";
                        changes.Add("privacy", newValueString);
                    }
                    if (e.StartDate != model.StartDate)
                        changes.Add("start date", model.StartDate.ToString());
                    if (e.EndDate != model.EndDate)
                        changes.Add("end date", model.EndDate.ToString());
                    if (e.Location != model.Location)
                        changes.Add("location", model.Location);

                    CreateNotification(e.Id, e.FullName, changes);

                    e.StartDate = model.StartDate;
                    e.EndDate = model.EndDate;
                    e.Description = model.Description;
                    e.Location = model.Location;
                    e.Name = model.Name;
                    e.MembersCanPost = model.MembersCanPost;
                    e.PrivacyType = Convert.ToInt16(model.Privacy);
                    Repository.SaveChanges();
                    return Json(model);
                }
                catch
                {
                    return View(model);
                }
            }
            return View(model);
        }

        
        //
        // POST: /Event/Delete/5
        [Authorize]
        [HttpPost]
        public ActionResult EventDelete(DeleteEventModel model)
        {
            try
            {
                var repo = Repository;
                var e = EventCompiledQueries.GetEvent(repo as Repository, model.Id);

                // try to check if the current user is creator of the event
                var user = CurrentUser;
                var admin = Repository.GetAdminOf(e.Id);
                if (admin == null || admin.Id != user.Id) // we check if current user is creator of event
                {
                    return RedirectToAction("ProfileView", "Profile", new { id = user.Id });
                }

                var relationships = RelationshipCompiledQueries.GetAllRelationshipsOf(repo as Repository, e.Id);
                foreach (var relationship in relationships)
                {
                    //delete relationship
                    Repository.DeleteObject(relationship);
                }
                var path = Server.MapPath("~/Media/" + e.Id + "/");
                if (Directory.Exists(path))
                {
                    Directory.Delete(path, true); // delete physical directory
                }
                Repository.SaveChanges();
                DeleteAllBaseObjects(e.Id);
                Repository.DeleteObject(e);
                Repository.SaveChanges();

                return RedirectToAction("EventOwnerList");
            }
            catch
            {
                return View(model);
            }
        }


        [Authorize]
        [HttpPost]
        public ActionResult EventRemove(DeleteEventModel model)
        {
            try
            {
                var repo = Repository;
                var e = EventCompiledQueries.GetEvent(repo as Repository, model.Id);


                var user = CurrentUser;
                var relationship = RelationshipCompiledQueries.GetMemberOfRelationship(repo as Repository, user.Id, e.Id);
                if(relationship != null)
                {
                    Repository.DeleteObject(relationship);
                    Repository.SaveChanges();
                }
                return RedirectToAction("EventOwnerList");
            }
            catch
            {
                return View(model);
            }
        }

        [Authorize]
        public ActionResult EventParticipants(Guid id)
        {
            var user = CurrentUser;
            var repo = Repository;
            var blockedFriends = RelationshipCompiledQueries.GetBlockedRelationships(repo as Repository, user.Id);
            var participants = Repository.GetMembersOf(id).Where(usr => !blockedFriends.Any(
                bl => (bl.BaseSubject.Id == usr.Id || bl.BaseSubject2.Id == usr.Id)));
              
//            var participantPageable = participants.GetPageable(page ?? 1, 50, (g => g.Created));
            var listParticipants = new List<SuggestedParticipants>();
            foreach (var participant in participants)
            {
                var participantProfilePicturePath = Repository.GetProfilePicturePath(participant.Id);
                var newParticipant = new SuggestedParticipants()
                                         {
                                             FullName = participant.FullName,
                                             Id = participant.Id,
                                             ProfilePicturePath = participantProfilePicturePath,
                                         };
                listParticipants.Add(newParticipant);
            }
            var model = new EventParticipants
            {
                EventId = id,
                CurrentUserId = user.Id,
                Participants = listParticipants.ToArray()
//                Page = listParticipants,
//                PageCount = participantPageable.PageCount,
//                PageIndex = participantPageable.PageIndex
            };
            return View(model);
        }

        [Authorize]
        public ActionResult InviteFriendsToEvent(Guid id)
        {
            var user = CurrentUser;

            var allFriends = Repository.GetFriendsOf(user.Id);
            var friendsLookupList = new List<FriendsLookupModels>();
            foreach (var friend in allFriends)
            {
                var newMember = new FriendsLookupModels()
                {
                    FirstName = friend.FirstName,
                    Fullname = friend.FullName,
                    LastName = friend.LastName,
                    Id = friend.Id,
                    ProfilePicturePath = Repository.GetProfilePicturePath(friend.Id),
                    Selected = false
                };
                friendsLookupList.Add(newMember);
            }
            var json = JsonHelper.Serialize(friendsLookupList);
            Session["allFriends"] = json;

            var model = new InviteEventModel
            {
                EventId = id,
                CurrentUserId = user.Id
                
            };
            return View(model);
        }

        [Authorize]
        [HttpPost]
        public ActionResult InviteFriendsToEvent(Guid id, InviteEventModel model)
        {
            if (model.UsersSelected == null)
            {
                return View(model);
            }
            var repo = Repository;
            //users that already got requested
            var usersAlreadyRequsted = UserCompiledQueries.UsersAlreadyRequested(repo as Repository, model.EventId);
            //useres who were selected and not requested already
            var selectedUsers =
                Repository.AsQueryable<User>().Where(
                    u => model.UsersSelected.Contains(u.Id) && !usersAlreadyRequsted.Contains(u.Id));
            var @event = EventCompiledQueries.GetEvent(repo as Repository, model.EventId);
            var currentUser = CurrentUser;
            foreach (var suggestedMemeberse in selectedUsers)
            {
                
                    var relationship = new Relationship
                    {
                        Id = Guid.NewGuid(),
                        PrivacyType = ObjectPrivacy.FriendsOnly,
                        BaseSubject = suggestedMemeberse,
                        BaseSubject2 = @event,
                        Created = DateTime.Now,
                        RelationType = RelationshipType.MemberOf,
                        Description = RelationshipType.MemberOfText,
                        Status = RelationshipStatus.Requested,
                        Type = ObjectType.Relationship,
                        Name = RelationshipType.MemberOfText
                    };
                    Repository.AddObject(relationship);
                    SendEmailConfirmEventInvitation(relationship);

                    //InvitesYou notification
                    var newNotification = new Notification()
                    {
                        Active = true,
                        BaseSubject = suggestedMemeberse,
                        Created = DateTime.Now,
                        Id = Guid.NewGuid(),
                        Type = BaseMessageType.Notification
                    };
                    var viewData3 = new
                    {
                        BaseSubjectType = "event",
                        SubjectId = model.EventId,
                        SubjectFullname = @event.FullName,
                        InviterId = model.CurrentUserId,
                        InviterFullname = currentUser.FullName
                    };

                    var viewDictionary3 = viewData3.ToViewDataDictionary();
                    newNotification.Content = ControlToString("~/Views/Notification/InvitesYou.cshtml", viewDictionary3);
                    Repository.AddObject(newNotification);

            }
            Repository.SaveChanges();

            return Json(model);
        }


        [Authorize]
        public ActionResult ChangeAdmin(Guid id)
        {

            var memebers = Repository.GetMembersOf(id);
            var friendsLookupList = new List<FriendsLookupModels>();
            foreach (var memeber in memebers)
            {
                var newMember = new FriendsLookupModels()
                {
                    FirstName = memeber.FirstName,
                    Fullname = memeber.FullName,
                    LastName = memeber.LastName,
                    Id = memeber.Id,
                    ProfilePicturePath = Repository.GetProfilePicturePath(memeber.Id),
                    Selected = false
                };
                friendsLookupList.Add(newMember);
            }
            var json = JsonHelper.Serialize(friendsLookupList);
            Session["allMembers"] = json;

            var model = new ChangeAdminModel
            {
                EventId = id,
                CurrentUserId = CurrentUser.Id,
                SubjectId = id
            };

            return View(model);
        }


        [Authorize]
        [HttpPost]
        public ActionResult ChangeAdmin(Guid id, ChangeAdminModel model)
        {
            var repo = Repository;
            var e = EventCompiledQueries.GetEvent(repo as Repository, id);
            var selectedMember = UserCompiledQueries.GetUser(repo as Repository, model.SelectedId);
            if(selectedMember != null)
            {
                //this is a temporary relationship till user doesnt accept it we will change his previous relationship to admin and we will delete this one
                var relationship = new Relationship
                {
                    Id = Guid.NewGuid(),
                    PrivacyType = ObjectPrivacy.FriendsOnly,
                    BaseSubject = selectedMember,
                    BaseSubject2 = e,
                    Created = DateTime.Now,
                    RelationType = RelationshipType.AdministratorOf,
                    Description = RelationshipType.AdministratorOfText,
                    Status = RelationshipStatus.Requested,
                    Type = ObjectType.Relationship,
                    Name = RelationshipType.AdministratorOfText
                };
                Repository.AddObject(relationship);
                Repository.SaveChanges();

                SendEmailConfirmAdminInvitation(relationship);

                return Json(model);
            }
            return View(model);
        }

        [Authorize]
        public ActionResult BecomeMember(Guid id)
        {
            var repo = Repository;
            var e = EventCompiledQueries.GetEvent(repo as Repository, id);
            var currentUser = CurrentUser;

            //try to look any relationship with currentUser and event e of type MemberOf independing of relationship status
            var previousRelationship = RelationshipCompiledQueries.AnyMemberRelationship(repo as Repository,
                                                                                         currentUser.Id, e.Id);
            if(previousRelationship != null)
            {
                previousRelationship.Status = RelationshipStatus.Confirmed;
                Repository.SaveChanges();
                CreateEventPost(previousRelationship,e); // create a post
            }
            // we create a new relationship with current user and event of type MemberOf and status confirmed
            else
            {
                var newRelationship = new Relationship()
                                          {
                                              BaseSubject = currentUser,
                                              BaseSubject2 = e,
                                              Created = DateTime.Now,
                                              Id = Guid.NewGuid(),
                                              Name = RelationshipType.MemberOfText,
                                              Description = RelationshipType.MemberOfText,
                                              PrivacyType = ObjectPrivacy.FriendsOnly,
                                              RelationType = RelationshipType.MemberOf,
                                              Status = RelationshipStatus.Confirmed,
                                              Type = ObjectType.Relationship
                                          };
                Repository.AddObject(newRelationship);
                Repository.SaveChanges();
                CreateEventPost(newRelationship, e); // create a post
            }
            return RedirectToAction("EventDetails", "Event", new {id = e.Id});
        }


        #region Subject members

        public override ActionResult ConfirmRelationshipNotification(Relationship relationship)
        {
            var model = new NotifyModel
                            {
                                Title = "Invite request",
                                Header = "Confirm event invite",
                                Body = "Event invite successfully confirmed.",
                                NotificationType = NotificationType.Notification
                            };

            return RedirectToAction("Notify", "Home", model);
        }

        public override ActionResult PostponeRelationshipNotification(Relationship relationship)
        {
            var model = new NotifyModel
                            {
                                Title = "Invite request",
                                Header = "Postpone event invite",
                                Body = "Event invite successfully postponed.",
                                NotificationType = NotificationType.Notification
                            };

            return RedirectToAction("Notify", "Home", model);
        }

        public override ActionResult PostponeFailedRelationshipNotification(Relationship relationship)
        {
            var model = new NotifyModel
                            {
                                Title = "Invite request",
                                Header = "Postpone event invite",
                                Body =
                                    "Invitation to event request couldn't be postponed, because the invitation was already confrirmed.",
                                NotificationType = NotificationType.Notification
                            };

            return RedirectToAction("Notify", "Home", model);
        }

        #endregion

        #region Email sending

        public bool SendEmailConfirmAdminInvitation(Relationship rel)
        {
            var user = CurrentUser;
            var baseSubject = rel.BaseSubject;
            var baseSubject2 = rel.BaseSubject2;
            var viewData = new
            {
                XSettings.SiteName,
                FriendName = baseSubject.FullName,
                YourName = user.FullName,
                EventName = ((Event)baseSubject2).Name,
                RelationshipId = rel.Id,
                ConfirmFriendshipUrl =
                    new Uri(HttpContext.Request.Url,
                            Url.Action("ConfirmAdminRelationship", "Event", new { id = rel.Id })).ToString(),
                PostponeFriendshipUrl =
                    new Uri(HttpContext.Request.Url,
                            Url.Action("PostponeRelationship", "Event", new { id = rel.Id })).ToString(),
                XSettings.SiteUrl,
                YourProfileUrl =
                    new Uri(HttpContext.Request.Url,
                            Url.Action("ProfileView", "Profile", new { id = user.Id })).ToString(),
                EventDetailsUrl =
                   new Uri(HttpContext.Request.Url,
                           Url.Action("EventDetails", "Event", new { id = baseSubject2.Id })).ToString()
            };
            var viewDictionary = viewData.ToViewDataDictionary();

            return SendTemplatedEmail(new List<string> { ((User)baseSubject).Email }, String.Format("{0} site: Administrator confirmation is required", XSettings.SiteName),
                                                   "~/Views/Email/ConfirmAdminInvitation.cshtml", viewDictionary);
        }

        public bool SendEmailConfirmEventInvitation(Relationship rel)
        {
            var user = CurrentUser;
            var baseSubject = rel.BaseSubject;
            var baseSubject2 = rel.BaseSubject2;
            var viewData = new
                               {
                                   XSettings.SiteName,
                                   FriendName = baseSubject.FullName,
                                   YourName = user.FullName,
                                   EventName = ((Event)baseSubject2).Name,
                                   RelationshipId = rel.Id,
                                   ConfirmFriendshipUrl =
                                       new Uri(HttpContext.Request.Url,
                                               Url.Action("ConfirmRelationship", "Event", new {id = rel.Id})).ToString(),
                                   PostponeFriendshipUrl =
                                       new Uri(HttpContext.Request.Url,
                                               Url.Action("PostponeRelationship", "Event", new {id = rel.Id})).ToString(),
                                   XSettings.SiteUrl,
                                   YourProfileUrl =
                                       new Uri(HttpContext.Request.Url,
                                               Url.Action("ProfileView", "Profile", new { id = user.Id })).ToString(),
                                   EventDetailsUrl =
                                      new Uri(HttpContext.Request.Url,
                                              Url.Action("EventDetails", "Event", new { id = baseSubject2.Id })).ToString()
                               };
            var viewDictionary = viewData.ToViewDataDictionary();

            return SendTemplatedEmail(new List<string> { ((User)baseSubject).Email }, String.Format("{0} site: Membership confirmation is required", XSettings.SiteName),
                                                   "~/Views/Email/ConfirmEventInvitation.cshtml", viewDictionary);
        }

        #endregion

        #region Extra functions


        public void DeleteAllBaseObjects(Guid eventId)
        {
            var repo = Repository;
            //find all posts from event
            var allPosts = PostCompiledQueries.GetAllPostsGeneral(repo as Repository, eventId);
            
            // if (Event->Post->BaseObject->SomeUser) and if (Event.delete->Post.delete !-> BaseObject->SomeUser)
            //BaseObject will be not deleted and it will not have post so we must delete it manually all BaseObjects connected with Event->Posts


            var allStatuses = Repository.AsQueryable<Status>().Where(st => allPosts.Any(pst => pst.BaseObject.Id == st.Id)).ToArray();
            foreach (var status in allStatuses)
            {
                Repository.DeleteObject(status);
            }
            var allNotes = Repository.AsQueryable<Note>().Where(no => allPosts.Any(pst => pst.BaseObject.Id == no.Id)).ToArray();
            foreach (var note in allNotes)
            {
                Repository.DeleteObject(note);
            }
            var allLinks = Repository.AsQueryable<Link>().Where(no => allPosts.Any(pst => pst.BaseObject.Id == no.Id)).ToArray();
            foreach (var link in allLinks)
            {
                Repository.DeleteObject(link);
            }
            var album = AlbumCompiledQueries.GetAlbumBySubjectId(repo as Repository, eventId); 
            var medias = MediaCompiledQueries.GetMediasOf(repo as Repository, album.Id);
            foreach (var media in medias)
            {
                Repository.DeleteObject(media);
            }
            Repository.DeleteObject(album);
            Repository.SaveChanges();
        }


        public void CreateNotification(Guid eventId, string eventFullname, Dictionary<string, string> values)
        {
            //create a notifications
            var members = Repository.GetMembersOf(eventId).ToList();
            var admin = Repository.GetAdminOf(eventId);
            members.Add(admin);
            foreach (var member in members)
            {
                foreach (var value in values)
                {
                    //GroupEventPageChange notification
                    var newNotification = new Notification()
                    {
                        Active = true,
                        BaseSubject = member,
                        Created = DateTime.Now,
                        Id = Guid.NewGuid(),
                        Type = BaseMessageType.Notification
                    };
                    var viewData3 = new
                    {
                        BaseSubjectType = "event",
                        SubjectId = eventId,
                        SubjectFullname = eventFullname,
                        Value = value.Key,
                        Value2 = value.Value
                    };

                    var viewDictionary3 = viewData3.ToViewDataDictionary();
                    newNotification.Content = ControlToString("~/Views/Notification/GroupEventPageChange.cshtml", viewDictionary3);
                    Repository.AddObject(newNotification);
                }

            }
            Repository.SaveChanges();
        }


        #endregion
    }
}